package torque.generated;

import java.awt.List;
import java.util.Collection;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Random;

import org.apache.torque.TorqueException;
import org.apache.torque.om.Persistent;
import org.apache.torque.util.Criteria;

import trolling.IO;

import java.util.*;

/**
 * 
 * Une {@link Partie} est une entité regroupant des {@link Trolldanspartie} et des {@link Objetdanspartie} sur des coordonnées x,y. Elle a un {@link Integer} largeur et un IDpartie.
 */
public class Partie extends torque.generated.BasePartie implements Persistent {
	/** Serial version */
	private static final long serialVersionUID = 1317634214273L;

	/** Ajoute le Troll t a la Partie
	 * @param t {@link Troll} a ajouter
	 * Initialises les parametres de jeux (points de vies, ect)
	 */
	public void ajouterTroll(Troll t) {
		try {
			System.out.println("Ajout de " + t.getNomtroll());
			Trolldanspartie tdp = new Trolldanspartie();
			tdp.setTroll(t);
			tdp.resetPV();
			int x;
			int y;
			java.util.List<Trolldanspartie> Teph = null;
			do {
				x = (int) Math.floor(Math.random() * this.getLargeur());
				y = (int) Math.floor(Math.random() * this.getLargeur());
				System.out.println(":) " + t.getNomtroll() + " est en " + x
						+ "," + y);
				Teph = TrolldanspartiePeer.getTrolls(x, y, this.getIdpartie());
			} while ((Teph.size() != 0));// sdfgsdfg
			tdp.setOrdre(2); // Le code le considerera comme non initialisé
			tdp.setX(x);
			tdp.setY(y);
			tdp.setPartie(this);
//			this.addTrolldanspartie(tdp);
			tdp.save();
			this.save();
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println(e.getMessage());
		}
	}

	/** Renvois l'objet a la position x,y de la partie
	 * @param x Position x telle que définie dans la partie
	 * @param y Position y 
	 * @return L'{@link Objetdanspartie} en question
	 *  ou Null si aucun objet trouvé
	 */
	public Objetdanspartie getObjet(int x, int y) {
		try {

			Criteria crit = new Criteria();
			crit.add(ObjetdanspartiePeer.XDEPART, x);
			crit.and(ObjetdanspartiePeer.YDEPART, y);
			crit.and(ObjetdanspartiePeer.IDPARTIE, this.getIdpartie());
			java.util.List<Objetdanspartie> objs = ObjetdanspartiePeer
					.doSelect(crit);
			crit = new Criteria();
			crit.add(ObjetdanstrolldanspartiePeer.XDEPART, x);
			crit.and(ObjetdanstrolldanspartiePeer.YDEPART, y);
			crit.and(ObjetdanstrolldanspartiePeer.IDPARTIE, this.getIdpartie());
			objs.removeAll(ObjetdanspartiePeer.doSelect(crit));

			if (objs.isEmpty()) {
				return null;
			}
			return objs.get(0);
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println(e.getMessage());
		}
		return null;
	}

	/**
	 * Ajoute x objets dans la map ( 1 obj pour 8 cases )
	 * 
	 * @param objs
	 *            listes des {@link Objet} parmis lesquels piocher
	 */
	public void ajouterObjets(java.util.List<Objet> objs) {
		if (objs.isEmpty()) {
			System.out.println("Pas d'objets dans la base !");
			return;
		}
		int nbobj = (int) Math
				.floor((this.getLargeur() * this.getLargeur()) / 5);
		System.out.println("Ajouts de " + nbobj
				+ " objets parmis une banque de " + objs.size() + " dans "
				+ (this.getLargeur() * this.getLargeur()) + " cases :");
		Objetdanspartie odp, odpeph;
		Objet obj;
		int x, y;
		Criteria crit;
		while (nbobj != 0) {
			try {
				int a = (int) Math.floor(Math.random() * objs.size());
				obj = objs.get(a);
				System.out.println("	[" + obj.getNomobjet()
						+ "] est tombé dans la partie !");
				odp = new Objetdanspartie();
				odp.setObjet(obj);
				odp.setIdpartie(this.getIdpartie());
				do {
					x = (int) Math.ceil(Math.random() * this.getLargeur());
					y = (int) Math.ceil(Math.random() * this.getLargeur());
					odpeph = this.getObjet(x, y);
				} while (odpeph != null);
				odp.setXdepart(x);
				odp.setYdepart(y);
				odp.save();
				nbobj--;
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				System.out.println(e.getMessage());
			}
		}
	}

	/** Retourne les Trolldanspartie avec des points de vies positifs
	 * @return {@link List}<{@link Trolldanspartie}> Liste des Trolls vivants dans la partie.
	 */
	public java.util.List<Trolldanspartie> getTrollVivants() {
		Criteria crit = new Criteria();
		crit.add(TrolldanspartiePeer.PV, 0, Criteria.GREATER_THAN);
		crit.add(TrolldanspartiePeer.IDPARTIE, this.getIdpartie());
		try {
			return TrolldanspartiePeer.doSelect(crit);
		} catch (Exception e) {
			System.out.println("Erreur au répupérage des trolls vivants");
			System.out.println(e.getMessage());
		}
		return null;
	}

	/**
	 * Evenement de nouveau tour initialisant les {@link Trolldanspartie} et les {@link Objetdanstrolldanspartie} liés a la partie.
	 *
	 */
	public void nouveauTour() {
		IO.clear();
		System.out.println("Initialisation du nouveau tour !");
		try {
			java.util.List<Trolldanspartie> trolls = this.getTrollVivants();
			for (Trolldanspartie t : trolls) {
				t.nouveauTour();
			}
			System.out.println("Ordre de jeu : ");
			int size = trolls.size();
			for (int i = 1; i < size + 1; i++) { // Attention, prototype
													// bizarre
				Trolldanspartie t = trolls.get((int) Math.floor(Math.random()
						* trolls.size()));
				t.setOrdre(i);
				System.out.println((i) + " - :) " + t.getNomtroll() + " ("
						+ t.getX() + "," + t.getY() + ") " + t.getPa() + "PA "
						+ t.getPv() + "PV");
				t.save();
				trolls.remove(t);
			}
		} catch (Exception e) {

			System.out.println("Erreur à l'initialisation du tour");
			System.out.println(e.getMessage());
		}
	}

	/** Fonction correspondant au choix du prochain {@link Trolldanspartie} a jouer.
	 * @return {@link Trolldanspartie} dont c'est le tour, ou Null si il faut réinitialiser un tour.
	 * 
	 */
	public Trolldanspartie StepTrolls() {
		try {
			java.util.List<Trolldanspartie> trolls = this.getTrollVivants();
			Trolldanspartie ret = null;
			for (Trolldanspartie t : trolls) {
				t.setOrdre(t.getOrdre() - 1);
				t.save();
				if (t.getOrdre() == 0) {
					ret = t;
				}
				// System.out.println(":) "+t.getNomtroll()+" "+t.getOrdre());
			}
			if (ret != null) {
				IO.clear();
				System.out.println("C'est au tour de " + ret.getNomtroll());
			}
			return ret;

		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/** Supprime une Partie en cascade (avec tout les elements enfants)
	 * @throws TorqueException Exception générées par les suppressions
	 */
	public void delete() throws TorqueException {
		java.util.List<Trolldanspartie> ts = this.getTrolldansparties();
		for (Trolldanspartie t : ts)
			t.delete();
		java.util.List<Objetdanspartie> os = this.getObjetdansparties();
		for (Objetdanspartie o : os)
			ObjetdanspartiePeer.doDelete(o);
		PartiePeer.doDelete(this);
		System.out.println("Partie Supprimée");
	}

}
